package com.ipay.core;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.ipay.utils.Constant;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * @author yangk
 */
public class QRCode {
    private static final Log log = LogFactory.getLog(QRCode.class);

    protected static byte[] createQRCode(String text, int margin, int width, int height) {
        Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
        hints.put(EncodeHintType.MARGIN, margin);
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        byte[] pngData = null;
        ByteArrayOutputStream pngOut = null;
        try {
            BitMatrix matrix = new QRCodeWriter().encode(text,
                    BarcodeFormat.QR_CODE,
                    width,
                    height,
                    hints);
            pngOut = new ByteArrayOutputStream();
            MatrixToImageWriter.writeToStream(matrix, "jpeg", pngOut);

            pngData = pngOut.toByteArray();
        } catch (WriterException e) {
            log.warn("write matrix to image error:", e);
        } catch (IOException e) {
            log.warn(e);
        } finally {
            if (pngOut != null) {
                try {
                    pngOut.close();
                } catch (IOException e) {
                    log.error(e);
                }
            }
        }
        return pngData;
    }

    public static void printQRCode(OutputStream os, String text, int margin, int width, int height) {
        byte[] img = createQRCode(text, margin, width, height);
        try {
            os.write(img);
        } catch (IOException e) {
            log.warn(e);
        }
    }

    public static void printQRCodeByLogo(OutputStream os, String text) {
        printQRCodeByLogo(os, text, 0, 215, 215);
    }

    public static void printQRCodeByLogo(OutputStream os, String text, String codeNo, String merchantCode) {
        printQRCodeByLogo(os, text, 0, 215, 215, codeNo, merchantCode);
    }

    public static void printQRCodeByLogo(OutputStream os, String text, int margin, int width, int height, String codeNo, String merchantCode) {
        BufferedImage img = createQRCodeByLogo(text, margin, width, height);
        try {
            ImageIO.write(img, "jpeg", os);
        } catch (IOException e) {
//			e.printStackTrace();
            log.warn(e);
        }
    }

    /**
     *
     * @param os
     * @param text
     * @param margin
     * @param width
     * @param height
     */
    public static void printQRCodeByLogo(OutputStream os, String text, int margin, int width, int height) {
        BufferedImage img = createQRCodeByLogo(text, margin, width, height);
        try {
            ImageIO.write(img, "jpeg", os);
        } catch (IOException e) {
//			e.printStackTrace();
            log.warn(e);
        }
    }

    public static BufferedImage createQRCodeByLogo(String text, int margin, int width, int height) {
        ByteArrayInputStream bis = null;
        try {
            /**
             * 读取二维码图片，并构建绘图对象
             */
            byte[] img = createQRCode(text, margin, width, height);
            bis = new ByteArrayInputStream(img);
            BufferedImage image = ImageIO.read(bis);

            Graphics2D g = image.createGraphics();
            /**
             * 读取Logo图片
             */
            //生产路径
            InputStream in = QRCode.class.getResourceAsStream("/paylogo.jpg");
            BufferedImage logo = ImageIO.read(in);
//			int widthLogo = image.getWidth() / 4, heightLogo = image.getHeight() / 4;
            int widthLogo = 48, heightLogo = 48;
            // 计算图片放置位置
            int x = (image.getWidth() - widthLogo) / 2;
            int y = (image.getHeight() - heightLogo) / 2;

            // 开始绘制图片
            g.drawImage(logo, x, y, widthLogo, heightLogo, null);
            g.setStroke(new BasicStroke(1));
            g.setColor(new Color(0xd0, 0xd0, 0xd0));
            g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);

            g.dispose();
            bis.close();
            in.close();
            return image;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    log.error(e);
                }
            }
        }

    }

    /**
     * @param file         店铺logo
     * @param head         公司名称
     * @param center       二维码内容
     * @return
     * @throws IOException
     */
    public static void printQRCodeByLogo(OutputStream os,File file, String head, String center, String codeNo) {
        try {
            BufferedImage img = getSeal(file, head, center, 420, 600, codeNo);
            ImageIO.write(img, "PNG", os);
        } catch (IOException e) {
            log.warn(e);
        }
    }
    /**
     * @param head         错误说明
     * @return
     * @throws IOException
     */
    public static void printErrorImg(OutputStream os,String head) {
        try {
            BufferedImage img = getErrorSeal(head, 420, 300);
            ImageIO.write(img, "PNG", os);
        } catch (IOException e) {
            log.warn(e);
        }
    }

    /**
     * @param file         店铺logo
     * @param head         公司名称
     * @param center       二维码内容
     * @param canvasWidth  二维码的宽  400
     * @param canvasHeight 二维码的高  500
     * @return
     * @throws IOException
     */
    public static BufferedImage getSeal(File file, String head, String center, int canvasWidth, int canvasHeight, String codeNo) throws IOException {
        BufferedImage bi = new BufferedImage(canvasWidth, canvasHeight, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = bi.createGraphics();
        InputStream inmb = QRCode.class.getResourceAsStream("/moban.jpg");
        BufferedImage logomb = ImageIO.read(inmb);
        // 开始绘制图片
        g2d.drawImage(logomb, 0, 0, canvasWidth, canvasHeight, null);

        //设置画笔
        //g2d.setPaint(Color.WHITE);
        //g2d.fillRect(0, 0, canvasWidth, canvasHeight);

        int circleRadius = Math.min(canvasWidth, canvasHeight) / 2;
        /***********draw circle*************/
        g2d.setPaint(Color.black);
        g2d.setStroke(new BasicStroke(5));//设置画笔的粗度d:\test2.jpg
        /*******************logo*****************/
        int widthLogo = 350,heightLogo = 60;
        int xlogo,ylogo = (int) (canvasHeight / 3.5 - heightLogo) / 2;
        if(file.exists()) {
            InputStream in = new FileInputStream(file);
        /*InputStream in = QRCode.class.getResourceAsStream("/hnhwly.jpg");*/
            BufferedImage logo = ImageIO.read(in);
            int height = logo.getHeight();
            int width = logo.getWidth();
            log.info("logo图片长宽width:"+width+"  = height: "+height);
            if(width - height >= 200 && (300 <= width && width <= 400) && (70 <= height && height <= 150)){
                heightLogo= (int) (height/1.3);
                ylogo = (int) (canvasHeight / 3.5 - heightLogo) / 2;
            }else{  //height:150-250   width:180-250
                widthLogo = 200;
                heightLogo= (int) (height/2);
                ylogo = (int) (canvasHeight / 3.5 - heightLogo) / 2;
            }
            xlogo=(canvasWidth-widthLogo)/2;
            // 开始绘制图片
            g2d.drawImage(logo, xlogo, ylogo, widthLogo, heightLogo, null);
        }
        /*******************公司名称*****************/
        int fontSize = 20;
        Font f = new Font("宋体", Font.BOLD, fontSize);
        FontRenderContext context = g2d.getFontRenderContext();
        Rectangle2D bounds = f.getStringBounds(head, context);
        g2d.setFont(f);
        //g2d.drawString(head, (float) (circleRadius - bounds.getCenterX()), (float) (circleRadius / 1.5 - bounds.getCenterY()));//heightLogo+ylogo
        g2d.drawString(head, (float) (circleRadius - bounds.getCenterX()), (float) (heightLogo+ylogo+40 + bounds.getCenterY()));//heightLogo+ylogo
        /*****************二维码******************/
        byte[] img = QRCode.createQRCode(center, 0, 215, 215);
        ByteArrayInputStream bis = new ByteArrayInputStream(img);
        BufferedImage image = ImageIO.read(bis);
        int x = (int) (circleRadius - 215 / 2);
        int y = (int) (canvasHeight - 215) / 2;
        g2d.drawImage(image, x, y, 215, 215, null);
        /*****************二维码里面的图片******************/
        InputStream in = QRCode.class.getResourceAsStream("/paylogo.jpg");
        BufferedImage logo = ImageIO.read(in);
        int widthdyLogo = 48;
        int heightdyLogo = 48;
        x = (int) (circleRadius - widthdyLogo / 2);
        y = (int) (canvasHeight - heightdyLogo) / 2;
        // 开始绘制图片
        g2d.drawImage(logo, x, y, widthdyLogo, heightdyLogo, null);
        /*****************二维码对应编码*******************/
        fontSize = 10;
        f = new Font("宋体", Font.BOLD, fontSize);
        context = g2d.getFontRenderContext();
        bounds = f.getStringBounds(codeNo, context);
        g2d.setFont(f);
        g2d.drawString(codeNo, (float) (circleRadius - bounds.getCenterX()), (float) (circleRadius * 2 - bounds.getCenterY()));
        /*****************提示信息*******************/
        /*fontSize = 12;
        f = new Font("宋体", Font.ITALIC, fontSize);
        context = g2d.getFontRenderContext();
        bounds = f.getStringBounds(foot, context);
        g2d.setFont(f);
        g2d.drawString(foot, (float) (circleRadius - bounds.getCenterX() / 1.1), (float) (circleRadius * 2.5 - bounds.getCenterY()));*/
        /*****************draw foot*******************/
        g2d.dispose();//销毁资源
        return bi;
    }



    /**
     * 错误 图片生成
     * @return
     * @throws IOException
     */
    public static BufferedImage getErrorSeal(String head, int canvasWidth, int canvasHeight) throws IOException {
        BufferedImage bi = new BufferedImage(canvasWidth, canvasHeight, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = bi.createGraphics();
        InputStream inmb = QRCode.class.getResourceAsStream("/errorMoban.jpg");
        BufferedImage logomb = ImageIO.read(inmb);
        // 开始绘制图片
        g2d.drawImage(logomb, 0, 0, canvasWidth, canvasHeight, null);
        //设置画笔
        //g2d.setPaint(Color.WHITE);
        //g2d.fillRect(0, 0, canvasWidth, canvasHeight);

        int circleRadius = Math.min(canvasWidth, canvasHeight) / 2;
        /***********draw circle*************/
        g2d.setPaint(Color.red);
        g2d.setStroke(new BasicStroke(5));//设置画笔的粗度d:\test2.jpg
        /*******************logo*****************/
        int widthLogo = 350,heightLogo = 60;
        int xlogo,ylogo = (int) (canvasHeight / 3.5 - heightLogo) / 2;

        /*******************公司名称*****************/
        int fontSize = 20;
        Font f = new Font("宋体", Font.BOLD, fontSize);
        FontRenderContext context = g2d.getFontRenderContext();
        Rectangle2D bounds = f.getStringBounds(head, context);
        g2d.setFont(f);
        g2d.drawString(head, (float) (circleRadius - bounds.getCenterX()/2+20), (float) (heightLogo+ylogo+40 + bounds.getCenterY()));//heightLogo+ylogo
        g2d.dispose();//销毁资源
        return bi;
    }

    public static void main(String[] args) throws Exception {
        //printQRCodeByLogo(new FileOutputStream("d:\\test.jpg"), "http://www.baidu.com", "", "");


        /*int canvasWidth = 400;
        int canvasHeight = 550;
        String savepath = "d:\\test22.jpg";

        //File fileLogo = new File(Constant.UPLOAD_IMG_PATH + "/D2017092916000000002/merchantInfo/234.jpg");
        File fileLogo = new File("F:\\jing\\documents\\source2\\pay-wechat\\src\\main\\webapp\\uploadQRCode\\hnhwly.jpg");
        String head = "湖南海外旅游";
        String center = "http://www.baidu.com";
        String foot = "支付宝支付，请将收款码保存至手机相册后使用。";
        String codeNo = "20170929767448";
        BufferedImage image = QRCode.getSeal(fileLogo, head, center, foot, canvasWidth, canvasHeight, codeNo);
        try {
            ImageIO.write(image, "PNG", new File(savepath));
        } catch (IOException e) {
            e.printStackTrace();
        }*/
    }

}
